#!/bin/bash

# ---------------------------------------------------------------------	#
# debautoinst	- Automatically install debian using debootstrap into	#
#		  partition or logical volume on LVM.			#
#									#
# version 0.1	- cj (2010-09-21) init.					#
# ---------------------------------------------------------------------	#

export LANG=C

DIST="squeeze"
SVR="ftp.th.debian.org"

# FTPSITE="$SVR"
FTPSITE="localhost:3142/$SVR"
VMFTPSITE="10.0.2.2:3142/$SVR"
# DEBREPO="http://$SVR/debian"
# DEBREPO="file:///var/cache/apt-cacher-ng/$SVR/debian"
DEBREPO="http://$FTPSITE/debian"

PKGLIST="tcpdump tshark netcat bind9-host rcs changetrack cfengine2"

USER="cj"
PASSWORD="coecj"
USERNAME="Chatchai J"

VMHOSTNAME="test"
MOUNT="mount"

fstab="/tmp/${VMHOSTNAME}.fstab"

# ---------------------------------------------------------------------	#
# Check that whether binary needed for this setup  is existed.		#
# ---------------------------------------------------------------------	#

check_command() {
	local CMD="$1"
	if [ ! -x "$CMD" ]; then
		echo "$CMD not exist."
		exit
	fi
}

# ---------------------------------------------------------------------	#
# Create various configuration files					#
# ---------------------------------------------------------------------	#

### ----- /etc/resolv.conf ----- ###
# It's difficult to generate /etc/resolv.conf by ourself,
# but it should be safe to copy from building host to the VM
# since it is likely to be used in the same environment.

create_resolv_conf() {
	local MOUNT="$1"

	[ -z "$MOUNT" ] && echo "ERR: resolv.conf" && exit
	sudo cp /etc/resolv.conf $MOUNT/etc
}

### ----- /etc/hosts ----- ###
# Standard /etc/hosts, without self IP address and name...
create_hosts() {
	local MOUNT="$1"

	[ -z "$MOUNT" ] && echo "ERR: hosts" && exit
	cat << _EOT_ > /tmp/hosts.$$
127.0.0.1	localhost localhost.localdomain

::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
_EOT_
	sudo mv -vf /tmp/hosts.$$ $MOUNT/etc/hosts
}

### ----- /etc/hostname ----- ###
create_hostname() {
	local MOUNT="$1"

	[ -z "$MOUNT" ] && echo "ERR: hostname" && exit
	sudo sh -c "(echo '$VMHOSTNAME' > $MOUNT/etc/hostname)"
}

### ----- /etc/fstab ----- ###
create_fstab() {
	local MOUNT="$1"

	[ -z "$MOUNT" ] && echo "ERR: fstab" && exit
	cat << _EOT_ > /tmp/fstab.$$
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
_EOT_
	cat $fstab >> /tmp/fstab.$$
	sudo mv -vf /tmp/fstab.$$ $MOUNT/etc/fstab
}

### ----- /etc/kernel-img.conf ----- ###
create_kernel_img_conf() {
	local MOUNT="$1"

	[ -z "$MOUNT" ] && echo "ERR: kernel-img.conf" && exit
	cat << _EOT_ > /tmp/kernel-img.conf.$$
do_symlinks = yes
relative_links = yes
do_bootloader = yes
do_bootfloppy = no
do_initrd = yes
link_in_boot = no
_EOT_
	sudo mv -vf /tmp/kernel-img.conf.$$ $MOUNT/etc/kernel-img.conf
}

### ----- /etc/apt/sources.list ----- ### packages update during install ###
create_tmp_apt_sources_list() {
	local MOUNT="$1"

	[ -z "$MOUNT" ] && echo "ERR: sources.list" && exit
	cat << _EOT_ > /tmp/sources.list.$$
deb http://${FTPSITE}/debian $DIST main
_EOT_
	sudo mv -vf /tmp/sources.list.$$ $MOUNT/etc/apt/sources.list
}

### ----- /etc/apt/sources.list ----- ### supposed to be real one ###
create_real_apt_sources_list() {
	local MOUNT="$1"
	
	[ -z "$MOUNT" ] && echo "ERR: sources.list" && exit
	cat << _EOT_ > /tmp/sources.list.$$
deb http://${FTPSITE}/debian $DIST main contrib non-free
deb http://${FTPSITE}/debian-security $DIST/updates main contrib non-free
_EOT_
	sudo mv -vf /tmp/sources.list.$$ $MOUNT/etc/apt/sources.list
}

### ----- /etc/apt/sources.list ----- ### real one using under VM ###
create_vm_apt_sources_list() {
	local MOUNT="$1"

	[ -z "$MOUNT" ] && echo "ERR: sources.list" && exit
	cat << _EOT_ > /tmp/final-sources.list.$$
deb http://${VMFTPSITE}/debian $DIST main contrib non-free
deb http://${VMFTPSITE}/debian-security $DIST/updates main contrib non-free
_EOT_
	sudo mv -vf /tmp/final-sources.list.$$ $MOUNT/etc/apt/sources.list
}

### ----- /etc/network/interfaces ----- ###
create_network_interfaces() {
	local MOUNT="$1"

	[ -z "$MOUNT" ] && echo "ERR: interfaces" && exit
	cat << _EOT_ > /tmp/interfaces.$$
auto lo
iface lo inet loopback

allow-hotplug eth0
iface eth0 inet dhcp
_EOT_

	sudo mv -f /tmp/interfaces.$$ $MOUNT/etc/network/interfaces
}

### ----- various config files in /etc ----- ###
create_config_files() {
	local MOUNT="$1"

	[ -z "$MOUNT" ] && echo "ERR: config files" && exit
	create_resolv_conf $MOUNT		# /etc/resolv.conf
	create_hosts $MOUNT			# /etc/hosts
	create_hostname $MOUNT			# /etc/hostname
	create_fstab $MOUNT			# /etc/fstab
	create_kernel_img_conf $MOUNT		# /etc/kernel_img_conf
	create_tmp_apt_sources_list $MOUNT	# /etc/apt/sources.list
	create_network_interfaces $MOUNT	# /etc/network/interfaces
}

# ---------------------------------------------------------------------	#
# create_policy_rc_d	Create policy-rc.d for handle tasksel tasks	#
#			install on chroot environment.			#
# ---------------------------------------------------------------------	#

create_policy_rc_d() {
	local MOUNT="$1"

	[ -z "$MOUNT" ] && echo "ERR: policy-rc.d" && exit
	cat << _EOT_ > /tmp/policy-rc.d.$$
#!/bin/sh
exit 101
_EOT_
	chmod a+rx /tmp/policy-rc.d.$$
	sudo mv -vf /tmp/policy-rc.d.$$ $MOUNT/usr/sbin/policy-rc.d
}

# ---------------------------------------------------------------------	#
# binding_mount		Binding mount points to chroot environment	#
# ---------------------------------------------------------------------	#

binding_mount() {
	local MOUNT="$1"

	[ -z "$MOUNT" ] && echo "ERR: mount" && exit
	# Binding mount point
	echo "Bind /proc to $MOUNT/proc"
	sudo mount --bind /proc $MOUNT/proc

	echo "Mount $MOUNT/dev/pts"
	sudo mount -t devpts none $MOUNT/dev/pts
}

# ---------------------------------------------------------------------	#
# binding_umount	Un-binding mount points from chroot environment	#
# ---------------------------------------------------------------------	#

binding_umount() {
	local MOUNT="$1"

	[ -z "$MOUNT" ] && echo "ERR: umount" && exit
	sudo umount $MOUNT/proc
	sudo umount $MOUNT/dev/pts
}

# ---------------------------------------------------------------------	#
# install_packages	Install additional packages			#
# ---------------------------------------------------------------------	#

install_packages() {
	local MOUNT="$1"
	local PKGLIST=""

	[ -z "$MOUNT" ] && echo "ERR: install_pacakges" && exit
	shift
	PKGLIST="$@"
	echo "Install additional package :: $PKGLIST"
	sudo chroot $MOUNT apt-get -y install $PKGLIST
}

# ---------------------------------------------------------------------	#
# Main Start Here							#
# ---------------------------------------------------------------------	#

[ -z "$1" ] && echo "Usage: $0 device" && exit

device="$1"

[ ! -b "$device" ] && echo "Hmm, '$device' is not a block device?" && exit

check_command /usr/sbin/debootstrap
check_command /bin/mount

echo "### ====================================================="
echo "### Create mount point '$MOUNT'"
echo "### ====================================================="

mkdir -p $MOUNT

echo "### ====================================================="
echo "### Mount filesystem to mount points"
echo "### ====================================================="

mke2fs -j $device
mount $device $MOUNT || {
	echo "Failed to mount '$device' to '$MOUNT'"
	exit
}

# Using debootstrap to install debian to raw disk image

DEBIAN_FRONTEND=noninteractive
DEBIAN_PRIORITY=critical
export DEBIAN_FRONTEND DEBIAN_PRIORITY

echo "### ====================================================="
echo "### Installing $DIST into $MOUNT"
echo "### ====================================================="

sudo debootstrap --arch i386 $DIST $MOUNT $DEBREPO

# Create various configuration files in mount point
echo "### ====================================================="
echo "### Create various config files"
echo "### ====================================================="

create_config_files $MOUNT

echo "### ====================================================="
echo "### Binding /proc and /dev/pts"
echo "### ====================================================="

binding_mount $MOUNT

# trap exit_cleanup EXIT INT

create_policy_rc_d $MOUNT

echo "### ====================================================="
echo "### Installing kernel into $MOUNT"
echo "### ====================================================="

sudo chroot $MOUNT apt-get update
sudo chroot $MOUNT apt-get -y install sudo gnupg grub linux-image-2.6-686

echo "### ====================================================="
echo "### Install sshd"
echo "### ====================================================="

sudo chroot $MOUNT apt-get -y install ssh
sudo chroot $MOUNT /etc/init.d/ssh stop

echo "### ====================================================="
echo "### Setup user account and predefined password"
echo "### ====================================================="
sudo chroot $MOUNT usermod -p '!' root

sudo chroot $MOUNT useradd -m -c "$USERNAME" -G sudo $USER
echo "$USER:$PASSWORD" | sudo chroot $MOUNT chpasswd  -c MD5 $USER

echo "### ====================================================="
echo "### Setup sudoers"
echo "### ====================================================="

sudo sh -c "(sed -ie 's/# %sudo/%sudo/' $MOUNT/etc/sudoers)"

echo "### ====================================================="
echo "### Install root's sshd key"
echo "### ====================================================="

sudo mkdir -p $MOUNT/root/.ssh
if [ -f ~/.ssh/id_rsa.pub ]; then
	sudo cp ~/.ssh/id_rsa.pub $MOUNT/root/.ssh/authorized_keys
fi
sudo chmod -R 755 $MOUNT/root/.ssh

if [ "$TASKLIST" ]; then
	echo "### ====================================================="
	echo "### Install preselected tasks"
	echo "### ====================================================="

	install_tasks $MOUNT $TASKLIST
fi

if [ "$PKGLIST" ]; then
	echo "### ====================================================="
	echo "### Install additional packages."
	echo "### ====================================================="

	install_packages $MOUNT $PKGLIST
fi

echo "### ====================================================="
echo "### Setup vm's /etc/apt/sources.list"
echo "### ====================================================="

create_vm_apt_sources_list $MOUNT

echo "### ====================================================="
echo "### Cleaning up"
echo "### ====================================================="

binding_umount $MOUNT

echo "Done."

# ---------------------------------------------------------------------	#
# end of file.								#
# ---------------------------------------------------------------------	#
